#include <sys/file.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

int main(int argc, char *argv[])
{
  int fd, lock;
  const char *lname;
  if (argc <3 ||strcmp(argv[1], "--help") == 0 || strchr("sx", argv[2][0]) == NULL)
    printf("usage: %s file locktype [sleep-time]\n",argv[0]);
  lock = (argv[2][0] == 's') ? LOCK_SH : LOCK_EX;
  if (argv[2][1] == 'n')
    lock |= LOCK_NB;
  fd = open(argv[1], O_RDONLY);
  if (fd == -1)
    printf("Failed to open file %s\n", argv[1]);
  lname = (lock & LOCK_SH)?"LOCK_SH":"LOCK_EX";
  printf("PID %ld: requesting %s \n", (long)getpid(), lname);
  if (flock(fd,lock) == -1)
    if (errno ==EWOULDBLOCK){
      printf("PID %ld: already locked\n",(long)getpid());
      exit(errno);
    }
    else {
      printf("Failed to lock file at %ld\n", (long)getpid());
      exit(-1);
    }
  printf("PID %ld: file lock granted %s\n",(long)getpid(), lname);

  sleep((argc > 3)?atoi(argv[3]):10);

  printf("PID %d: releasing %s\n",getpid(), lname);
  if (flock(fd, LOCK_UN) == -1)
    printf("Faild to flock\n");
  return 0;
}
